package com.alibaba.citrus.ots.platform.enhance.facade.service;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.platform.enhance.repository.ChannelRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.OrganizationRelationRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.OrganizationRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.ScItemGroupRepository;
import com.alibaba.cz.base.model.store.ChannelSDO;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.otsplatformenhance.api.organizationquery.dto.GetOrganizationByTypeRequest;
import com.epoch.app.otsplatformenhance.api.organizationquery.dto.GetOrganizationByTypeResponse;
import com.epoch.app.otsplatformenhance.api.organizationquery.dto.GetOrganizationsByOutCodesRequest;
import com.epoch.app.otsplatformenhance.api.organizationquery.dto.SortSelectBoxByLabelRequest;
import com.epoch.app.otsplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.otsplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.otsplatformenhance.dto.request.QueryScItemGroupRequest;
import com.epoch.app.otsplatformenhance.enums.OrganizationRelevanceTypeEnum;
import com.epoch.app.otsplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.otsplatformenhance.sdo.OrganizationRelationSDO;
import com.epoch.app.otsplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.otsplatformenhance.sdo.ScItemGroupSDO;
import com.epoch.app.otsplatformenhance.service.OtsPlatformEnhanceService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.Collator;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhoubc
 * @description: TODO
 * @date 2021/9/3 12:26
 */
@Primary
@Service
public class OrganizationQueryServiceImpl implements OrganizationQueryService {

    private static final String MENGNIU_GROUP = "1";
    private static final String ENTERPRISE_GROUP_CODE = "6000";
    @Resource
    OrganizationRepository organizationRepository;

    @Resource
    OrganizationRelationRepository organizationRelationRepository;

    @Resource
    ChannelRepository channelRepository;

    @Resource
    ScItemGroupRepository scItemGroupRepository;

    @Resource
    BaseDataService baseDataService;

    @Resource
    OtsPlatformEnhanceService otsPlatformEnhanceService;

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getAllOrganization() {
        List<OrganizationSDO> platformOrgList = organizationRepository.getAllOrganization();
        return Result.success(convertToTree(platformOrgList, "1"));
    }

    @Override
    @FacadeInvoker
    public Result<OrganizationSDO> getOrganizationDetail(IdQueryRequest request) {
        OrganizationSDO sdo = organizationRepository.getOrganizationById(request.getId());
        enrichOrganizationSDO(sdo);
        return Result.success(sdo);
    }

    @Override
    @FacadeInvoker
    public Result<OrganizationSDO> getParentOrganization(IdQueryRequest request) {
        OrganizationSDO org = organizationRepository.getOrganizationById(request.getId());
        OrganizationSDO parentOrg = null;
        if (org.getParentId() != null) {
            parentOrg = organizationRepository.getOrganizationById(org.getParentId());
        }
        return Result.success(parentOrg);
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getTopOrganizationList(IdQueryRequest request) {
        Integer targetType = request.getType() != null ? request.getType() : OrganizationTypeEnum.COMPANY.getCode();
        if (targetType > OrganizationTypeEnum.SALES_DEPARTMENT.getCode() || targetType < OrganizationTypeEnum.GROUP.getCode()) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-16-001"));
        }
        List<OrganizationSDO> result = new ArrayList<>();
        OrganizationSDO sdo = organizationRepository.getOrganizationById(request.getId());
        if (sdo == null) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-16-003"));
        }
        result.add(sdo);
        if (targetType > sdo.getType()) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-15-009"));
        }
        OrganizationSDO temp = sdo;
        for (int i = sdo.getType(); i > targetType; i--) {
            temp = organizationRepository.getOrganizationById(temp.getParentId());
            result.add(temp);
        }
        return Result.listSuccess(result, result.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getAllChildOrganizations(IdQueryRequest request) {
        OrganizationSDO sdo = organizationRepository.getOrganizationById(request.getId());
        if (sdo == null) {
            return Result.success(null);
        }
        return Result.success(convertToTree(queryAllChildOrganization(sdo), request.getId()));
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getAllChildOrganizationList(IdQueryRequest request) {
        OrganizationSDO sdo = organizationRepository.getOrganizationById(request.getId());
        if (sdo == null) {
            return Result.success(null);
        }
        List<OrganizationSDO> result = queryAllChildOrganization(sdo);
        return Result.listSuccess(result, result.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getAllChildOrganizationListByCompanyOrgIds(IdQueryRequest request) {
        List<OrganizationSDO> result = new ArrayList<>();
        List<OrganizationSDO> orgs = organizationRepository.getOrganizationByIds(request.getIds());
        result.addAll(orgs);
        List<String> parentIds = Lists.newArrayList(request.getIds());
        for (int i = OrganizationTypeEnum.SALES_ORGANIZATION.getCode().intValue(); i <= OrganizationTypeEnum.SALES_DEPARTMENT.getCode().intValue(); i++) {
            List<OrganizationSDO> list = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(i), null, parentIds);
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            result.addAll(list);
            parentIds = list.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
        }
        return Result.listSuccess(result, result.size());
    }

    public List<OrganizationSDO> queryAllChildOrganization(OrganizationSDO sdo) {
        List<OrganizationSDO> result = new ArrayList<>();
        result.add(sdo);
        if (Objects.equals(sdo.getType(), OrganizationTypeEnum.SALES_DEPARTMENT.getCode())) {
            return result;
        }
        List<String> parentIds = new ArrayList<>();
        parentIds.add(sdo.getId());
        for (int i = sdo.getType() + 1; i <= OrganizationTypeEnum.SALES_DEPARTMENT.getCode().intValue(); i++) {
            List<OrganizationSDO> list = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(i), null, parentIds);
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            result.addAll(list);
            parentIds = list.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
        }
        return result;
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> queryAllChildOrganizationToTargetType(IdQueryRequest idQueryRequest) {
        String rootId = idQueryRequest.getId();
        Integer targetType = idQueryRequest.getType();
        //向下查询指定的type必须是100-106
        if (targetType < OrganizationTypeEnum.GROUP.getCode() || targetType > OrganizationTypeEnum.SALES_DEPARTMENT.getCode()) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-15-010"));
        }
        OrganizationSDO sdo = organizationRepository.getOrganizationById(rootId);
        if (sdo == null) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-16-003"));
        }
        List<OrganizationSDO> result = new ArrayList<>();
        result.add(sdo);
        if (Objects.equals(sdo.getType(), OrganizationTypeEnum.SALES_DEPARTMENT.getCode())) {
            return Result.listSuccess(result,result.size());
        }
        List<String> parentIds = new ArrayList<>();
        parentIds.add(rootId);
        for (int i = sdo.getType() + 1; i <= targetType.intValue(); i++) {
            List<OrganizationSDO> list = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(i), null, parentIds);
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            result.addAll(list);
            parentIds = list.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
        }
        return Result.listSuccess(result,result.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationRelationSDO>> getOrgScItemGroupRelationByOrgId(IdQueryRequest request) {
        if (StringUtil.isBlank(request.getId()) && CollectionUtils.isEmpty(request.getIds())) {
            return Result.listSuccess(null, 0);
        }
        request.setType(OrganizationRelevanceTypeEnum.SCITEMGROUP.getCode());
        PageResult<List<OrganizationRelationSDO>> pageResult = organizationRelationRepository.getOrganizationRelationByOrgId(request);
        enrichOrgScItemList(pageResult.getContent());
        return Result.listSuccess(pageResult.getContent(), pageResult.getContent().size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationRelationSDO>> getOrgChannelRelationByOrgId(IdQueryRequest request) {
        request.setType(OrganizationRelevanceTypeEnum.CHANNEL.getCode());
        request.setStatus(request.getStatus());
        PageResult<List<OrganizationRelationSDO>> pageResult = organizationRelationRepository.getOrganizationRelationByOrgId(request);
        enrichOrgChannelList(pageResult.getContent());
        return Result.listSuccess(pageResult.getContent(), pageResult.getContent().size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationRelationSDO>> getOrgChannelRelationByChannelId(IdQueryRequest request) {
        if (StringUtil.isBlank(request.getId())) {
            return Result.listSuccess(null, 0);
        }
        request.setRelevanceId(request.getId());
        if (StringUtil.isNotEmpty(request.getCode())) {
            List<ChannelSDO> channels = channelRepository.batchQueryChannelByCodes(Lists.newArrayList(request.getCode()));
            if (CollectionUtils.isEmpty(channels)) {
                return Result.listSuccess(null, 0);
            }
            request.setRelevanceId(channels.get(0).getChannelId());
        }
        request.setType(OrganizationRelevanceTypeEnum.CHANNEL.getCode());
        PageResult<List<OrganizationRelationSDO>> pageResult = organizationRelationRepository.getOrganizationRelationByRelevanceId(request);
        return Result.listSuccess(pageResult.getContent(), pageResult.getContent().size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getOrganizationsByOutCodes(GetOrganizationsByOutCodesRequest getOrganizationsByOutCodesRequest) {
        List<OrganizationSDO> organizationSDOS = organizationRepository.getOrganizationByOutCodes((List<String>) getOrganizationsByOutCodesRequest.getOutCodes());
        if (CollectionUtils.isEmpty(organizationSDOS)) {
            return Result.listEmptySuccess();
        }
        return Result.listSuccess(organizationSDOS, organizationSDOS.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getEmployeeOrganization(IdQueryRequest request) {
        String rootOrganizationId = request.getId();//tree root organizationId
        OrganizationSDO sdo = organizationRepository.getOrganizationById(rootOrganizationId);
        if (sdo == null) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-16-003"));
        }
        //员工关联的组织 在分子公司层级及以下处理
        if (OrganizationTypeEnum.COMPANY.getCode() <= sdo.getType()) {
            List<OrganizationSDO> allChildOrg = convertToTree(queryAllChildOrganization(sdo), rootOrganizationId);
            return Result.success(allChildOrg);
            //员工关联的组织 在分子公司层级以上，查出所有业务单元组织包括业务单元下的所有子孙组织
        } else {
//            List<OrganizationSDO> allOrg = new ArrayList<>();
//            IdQueryRequest idQueryRequest =new IdQueryRequest();
//            idQueryRequest.setId(rootOrganizationId);
//            idQueryRequest.setType(OrganizationTypeEnum.COMPANY.getCode());
//            Result<List<OrganizationSDO>> companyOrgList = getDownQueryOrganization(idQueryRequest);
//            List<String> bizIds = companyOrgList.getResult().stream().map(org ->{
//                return org.getBizId();
//            }).collect(Collectors.toList());
//
//            List<OrganizationSDO> temp = new ArrayList<>();
//            for(int i = OrganizationTypeEnum.COMPANY.getCode(); i <= OrganizationTypeEnum.SALES_DEPARTMENT.getCode(); i++){
//                List<OrganizationSDO> list = organizationRepository.getOrganizationsByType(OrganizationBizTypeEnum.COMPANY.getCode(), null, bizIds, String.valueOf(i),null,null);
//                temp.addAll(list);
//            }
//            companyOrgList.getResult().forEach(org -> {
//                List<OrganizationSDO> companyOrgTree = convertToTree(temp, org.getId());
//                allOrg.addAll(companyOrgTree);
//            });
//            return Result.success(allOrg);
            return Result.success(null);
        }
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getDownQueryOrganization(IdQueryRequest idQueryRequest) {
        String id = idQueryRequest.getId();//组织id
        Integer targetType = idQueryRequest.getType();//向下查询指定的type
        if(StringUtils.isBlank(id) || MENGNIU_GROUP.equals(id)){
            com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Request byCodes2Request = new com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Request();
            byCodes2Request.setIds(Lists.newArrayList(ENTERPRISE_GROUP_CODE));

            com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Response response = baseDataService.baselineGetOrganizationByCodes2(byCodes2Request);
//            log.info("getDownQueryOrganization 获取常温事业部组织,response={}", JSON.toJSONString(response));
            if(null != response && CollectionUtils.isNotEmpty(response.getResult())){
                com.epoch.app.bcots.model.dto.OrganizationSDO organizationSDO = response.getResult().get(0);
                idQueryRequest.setId(organizationSDO.getId());
                id = organizationSDO.getId();
            }
        }

        List<OrganizationSDO> result = new ArrayList<>();
        //向下查询指定的type必须是分子公司层级及以下
        if (targetType < OrganizationTypeEnum.COMPANY.getCode() || targetType > OrganizationTypeEnum.SALES_DEPARTMENT.getCode()) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-15-010"));
        }
        OrganizationSDO parentOrg = organizationRepository.getOrganizationById(id);
        if (parentOrg == null) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-16-003"));
        }
        if (parentOrg.getType() > targetType) {
            return Result.success(null);
        }
        if (Objects.equals(parentOrg.getType(), targetType)) {
            result.add(parentOrg);
            return Result.listSuccess(enichOrgList(result), result.size());
        }
        Result<List<OrganizationSDO>> listResult =  getAllChildOrganizationList(idQueryRequest);
        if(listResult.isSuccess() && CollectionUtils.isNotEmpty(listResult.getResult())){
            List<OrganizationSDO> list = listResult.getResult();
            if(null!=targetType){
                list = list.stream().filter((organizationSDO)->organizationSDO.getType().equals(targetType)).collect(Collectors.toList());
            }
            return Result.listSuccess(enichOrgList(list), list.size());
        }
//        List<OrganizationSDO> allCompanyOrg = new ArrayList<>();
//        //组织id是总公司组织，查出对应的所有公司
//        if (parentOrg.getType() < OrganizationTypeEnum.COMPANY.getCode()) {
//            if (Objects.equals(OrganizationTypeEnum.GROUP.getCode(), parentOrg.getType())) {
//                //蒙牛集团组织，直接查指定层级组织
//                result = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(targetType), null, null);
//                return Result.listSuccess(enichOrgList(result), result.size());
//            } else if (Objects.equals(OrganizationTypeEnum.ENTERPRISE_GROUP.getCode(), parentOrg.getType())) {
//                List<OrganizationSDO> regionList = organizationRepository.getDirectChildOrganizations(id, null);
//                List<String> regionOrgIds = regionList.stream().map(org -> {
//                    return org.getId();
//                }).collect(Collectors.toList());
//                allCompanyOrg = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(OrganizationTypeEnum.COMPANY.getCode()), null, regionOrgIds);
//            } else if (Objects.equals(OrganizationTypeEnum.REGION.getCode(), parentOrg.getType())) {
//                allCompanyOrg = organizationRepository.getDirectChildOrganizations(id, null);
//            }
//        }
//
//        if (CollectionUtils.isEmpty(allCompanyOrg)) {
//            if (Objects.equals(OrganizationTypeEnum.COMPANY.getCode(), parentOrg.getType())) {
//                result = organizationRepository.getOrganizationsByType(parentOrg.getBizType(), parentOrg.getBizId(), null, String.valueOf(targetType), null, null);
//            } else if (Objects.equals(OrganizationTypeEnum.SALES_ORGANIZATION.getCode(), parentOrg.getType())) {
//                List<OrganizationSDO> channelOrgList = organizationRepository.getDirectChildOrganizations(parentOrg.getId(), null);
//                if (Objects.equals(OrganizationTypeEnum.SALES_CHANNEL.getCode(), targetType)) {
//                    result.addAll(channelOrgList);
//                } else if (Objects.equals(OrganizationTypeEnum.SALES_DEPARTMENT.getCode(), targetType)) {
//                    List<String> channelOrgIds = channelOrgList.stream().map(org -> {
//                        return org.getId();
//                    }).collect(Collectors.toList());
//                    result = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(OrganizationTypeEnum.SALES_DEPARTMENT.getCode()), null, channelOrgIds);
//                }
//            } else if (Objects.equals(OrganizationTypeEnum.SALES_CHANNEL.getCode(), parentOrg.getType())) {
//                List<OrganizationSDO> departmentOrgList = organizationRepository.getDirectChildOrganizations(parentOrg.getId(), null);
//                result.addAll(departmentOrgList);
//            } else if (Objects.equals(OrganizationTypeEnum.SALES_DEPARTMENT.getCode(), parentOrg.getType())) {
//                result.add(parentOrg);
//            }
//        } else {
//            if (Objects.equals(OrganizationTypeEnum.COMPANY.getCode(), targetType)) {
//                return Result.listSuccess(enichOrgList(allCompanyOrg), allCompanyOrg.size());
//            }
//            List<String> bizIds = allCompanyOrg.stream().map(org -> {
//                return org.getBizId();
//            }).collect(Collectors.toList());
//
//            result = organizationRepository.getOrganizationsByType(OrganizationBizTypeEnum.COMPANY.getCode(), null, bizIds, String.valueOf(targetType), null, null);
//        }
        return Result.listSuccess(Lists.newArrayList(), 0);
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getEntireOrgTreeById(IdQueryRequest idQueryRequest) {
        String id = idQueryRequest.getId();//组织id
        Integer targetType = OrganizationTypeEnum.SALES_DEPARTMENT.getCode();//向下查询指定的type
        List<OrganizationSDO> result = new ArrayList<>();
        OrganizationSDO org = organizationRepository.getOrganizationById(id);
        if (org == null) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-16-003"));
        }

        result.add(org);
        IdQueryRequest queryRequest = new IdQueryRequest();
        queryRequest.setId(id);
        queryRequest.setType(OrganizationTypeEnum.GROUP.getCode());
        List<OrganizationSDO> topOrgList = getTopOrganizationList(queryRequest).getResult();
        topOrgList.remove(0);
        topOrgList.forEach(x -> {
            x.setDisabled(true);
        });
        result.addAll(topOrgList);

        List<String> tempParentIds = new ArrayList<>();
        tempParentIds.add(org.getId());
        for (int i = org.getType() + 1; i <= targetType; i++) {
            List<OrganizationSDO> list = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(i), null, tempParentIds);
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            tempParentIds = list.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
            result.addAll(list);
        }
        return Result.success(convertToTree2(result, "1"));
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getAnyTreeById(IdQueryRequest idQueryRequest) {
        String id = idQueryRequest.getId();//组织id
        Integer targetType = idQueryRequest.getType();//向下查询指定的type
        List<OrganizationSDO> result = new ArrayList<>();
        //向下查询指定的type必须是分子公司层级及以下
        if (targetType < OrganizationTypeEnum.COMPANY.getCode() || targetType > OrganizationTypeEnum.SALES_DEPARTMENT.getCode()) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-15-010"));
        }
        OrganizationSDO parentOrg = organizationRepository.getOrganizationById(id);
        if (parentOrg == null) {
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-16-003"));
        }
        if (parentOrg.getType() > targetType) {
            return Result.success(null);
        }
        result.add(parentOrg);
        if (Objects.equals(parentOrg.getType(), targetType)) {
            parentOrg.setChildren(new ArrayList<>());
            return Result.listSuccess(enichOrgList(result), result.size());
        }

        List<String> tempParentIds = new ArrayList<>();
        tempParentIds.add(parentOrg.getId());
        for (int i = parentOrg.getType() + 1; i <= targetType; i++) {
            List<OrganizationSDO> list = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(i), null, tempParentIds);
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            tempParentIds = list.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
            result.addAll(list);
        }
        List treeList = convertToTree(result, parentOrg.getId());
        recursiveList(treeList);
        return Result.success(treeList);
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> getAllCompanyTree(IdQueryRequest idQueryRequest) {
        List<OrganizationSDO> result = new ArrayList<>();
        List<String> queryIds = new ArrayList<>();
        if (StringUtil.isNotEmpty(idQueryRequest.getId())) {
            queryIds.add(idQueryRequest.getId());
        }
        if (CollectionUtils.isNotEmpty(idQueryRequest.getIds())) {
            queryIds.addAll(idQueryRequest.getIds());
        }
        List<String> parentIds = new ArrayList<>();
        //组织id为空，默认查所有公司组织树
        if (CollectionUtils.isEmpty(queryIds)) {
            List<OrganizationSDO> companyOrgs = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(OrganizationTypeEnum.COMPANY.getCode()), null, null);
            result.addAll(companyOrgs);
            parentIds = companyOrgs.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
        } else {
            List<OrganizationSDO> orgs = organizationRepository.getOrganizationByIds(queryIds);
            List<OrganizationSDO> companyOrgs = orgs.stream().filter(x ->
                    Objects.equals(x.getType(), OrganizationTypeEnum.COMPANY.getCode())
            ).collect(Collectors.toList());
            result.addAll(companyOrgs);
            parentIds = companyOrgs.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
        }
        //公司组织id就是根节点
        List<String> rootIds = parentIds;

        for (int i = OrganizationTypeEnum.SALES_ORGANIZATION.getCode(); i <= OrganizationTypeEnum.SALES_DEPARTMENT.getCode().intValue(); i++) {
            List<OrganizationSDO> list = organizationRepository.getOrganizationsByType(null, null, null, String.valueOf(i), null, parentIds);
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            result.addAll(list);
            parentIds = list.stream().map(x -> {
                return x.getId();
            }).collect(Collectors.toList());
        }
        List treeList = convertToTrees(result, rootIds);
        recursiveList(treeList);
        return Result.listSuccess(treeList, parentIds.size());
    }

    @Override
    @FacadeInvoker
    public Result<List<OrganizationSDO>> sortSelectBoxByLabel(SortSelectBoxByLabelRequest sortSelectBoxByLabelRequest) {
        if (CollectionUtils.isEmpty(sortSelectBoxByLabelRequest.getOrganizationList())) {
            return Result.listSuccess(null, 0);
        }
        String sortField = StringUtil.isBlank(sortSelectBoxByLabelRequest.getSortField())?"label":sortSelectBoxByLabelRequest.getSortField();
        List<OrganizationSDO> list = Lists.newArrayList(sortSelectBoxByLabelRequest.getOrganizationList());
        Comparator comparator = Collator.getInstance(Locale.CHINA);
        Collections.sort(list, new Comparator<OrganizationSDO>() {
            @Override
            public int compare(OrganizationSDO o1, OrganizationSDO o2) {
                if ("label".equals(sortField)) {
                    return comparator.compare(o1.getLabel(), o2.getLabel());
                } else if ("code".equals(sortField)) {
                    if (StringUtil.isBlank(o1.getCode()) || StringUtil.isBlank(o2.getCode())) {
                        return 1;
                    }
                    return comparator.compare(o1.getCode(), o2.getCode());
                } else {
                    return 1;
                }
            }
        });
        return Result.listSuccess(list, list.size());
    }

    @Override
    @FacadeInvoker
    public GetOrganizationByTypeResponse getOrganizationByType(GetOrganizationByTypeRequest request) {
        GetOrganizationByTypeResponse response = new GetOrganizationByTypeResponse();
        Result<List<OrganizationSDO>> organizationRes= getOrganizationByTypeAndBizIdAndBizType(request.getType(),null,null);
        if(CollectionUtils.isNotEmpty(organizationRes.getResult())){
            List<OrganizationSDO> organizationSDOS = enichOrgList(organizationRes.getResult());
            response.setResult(organizationSDOS);
            return response;
        }
//        List<OrganizationSDO> organizationsByType = organizationRepository.getOrganizationsByType(null, null, null, getOrganizationByTypeRequest.getType(), null, null);
//        if (CollectionUtils.isNotEmpty(organizationsByType)) {
//            List<OrganizationSDO> organizationSDOS = enichOrgList(organizationsByType);
//            response.setResult(organizationSDOS);
//            return response;
//        }
        return response;
    }

    public Result<List<OrganizationSDO>> getOrganizationByTypeAndBizIdAndBizType(String type,String bizId,String bizType) {
        Integer targetType = Integer.parseInt(type);//向下查询指定的type
        List<OrganizationSDO> organizationSDOS = Lists.newArrayList();

        com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Request byCodes2Request = new
                com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Request();
        byCodes2Request.setIds(Lists.newArrayList(ENTERPRISE_GROUP_CODE));

        com.epoch.app.bcots.model.dto.BaselineGetOrganizationByCodes2Response response = baseDataService.baselineGetOrganizationByCodes2(byCodes2Request);
        if(null != response && CollectionUtils.isNotEmpty(response.getResult())){
            IdQueryRequest idQueryRequest = new IdQueryRequest();
            idQueryRequest.setId(response.getResult().get(0).getId());
            Result<List<OrganizationSDO>> listResult =  getAllChildOrganizationList(idQueryRequest);
            if(listResult.isSuccess() && CollectionUtils.isNotEmpty(listResult.getResult())){
                organizationSDOS = listResult.getResult();
                if(null!=targetType){
                    organizationSDOS = organizationSDOS.stream().filter((organizationSDO)->organizationSDO.getType().equals(targetType)).collect(Collectors.toList());
                }
            }
        }
        if(StringUtils.isNotBlank(bizId)){
            organizationSDOS = organizationSDOS.stream().filter((o)->o.getBizId().equals(bizId)).collect(Collectors.toList());
        }
        if(StringUtils.isNotBlank(bizType)){
            organizationSDOS = organizationSDOS.stream().filter((o)->o.getBizType().equals(bizType)).collect(Collectors.toList());
        }
        return Result.listSuccess(enichOrgList(organizationSDOS),organizationSDOS.size());

    }

    private List<OrganizationSDO> enichOrgList(List<OrganizationSDO> list) {
        list.forEach(org -> {
            org.setLabel(org.getName());
            org.setValue(org.getId());
        });
        return list;
    }

    private void enrichOrganizationSDO(OrganizationSDO sdo) {
        if (sdo == null) {
            return;
        }
        if (!"0".equals(sdo.getParentId())) {
            OrganizationSDO parentOrganization = organizationRepository.getOrganizationById(sdo.getParentId());
            sdo.setParentName(parentOrganization.getName());
        } else {
            sdo.setParentName("无");
        }
    }

    private void enrichOrgChannelList(List<OrganizationRelationSDO> organizationRelList) {
        if (CollectionUtils.isEmpty(organizationRelList)) {
            return;
        }
        List<String> idList = organizationRelList.stream().map(sdo -> {
            return sdo.getRelevanceId();
        }).collect(Collectors.toList());

        List<ChannelSDO> channelList = channelRepository.batchQueryChannel(idList);
        Map<String, ChannelSDO> channelMap = Nullable.stream(channelList).collect(Collectors.toMap(ChannelSDO::getChannelId, Function.identity(), (v1, v2) -> v1));
        organizationRelList.forEach(sdo -> {
            ChannelSDO channelSDO = channelMap.get(sdo.getRelevanceId());
            if (channelSDO != null) {
                sdo.setName(channelSDO.getChannelName());
                sdo.setCode(channelSDO.getChannelCode());
                sdo.setOutCode(channelSDO.getOutCode());
            }
        });
    }

    private void enrichOrgScItemList(List<OrganizationRelationSDO> organizationRelList) {
        List<String> idList = organizationRelList.stream().map(sdo -> {
            return sdo.getRelevanceId();
        }).collect(Collectors.toList());

        QueryScItemGroupRequest request = new QueryScItemGroupRequest();
        request.setIdList(idList);
        request.setLimit(100);
        PageResult<List<ScItemGroupSDO>> pageResult = scItemGroupRepository.pageQueryScItemGroupList(request);
        if (pageResult.getContent() == null) {
            return;
        }
        Map<String, ScItemGroupSDO> scItemGroupMap = pageResult.getContent().stream().collect(Collectors.toMap(ScItemGroupSDO::getId, Function.identity(), (v1, v2) -> v1));
        organizationRelList.forEach(sdo -> {
            ScItemGroupSDO scItemGroupSDO = scItemGroupMap.get(sdo.getRelevanceId());
            sdo.setName(scItemGroupSDO.getName());
            sdo.setCode(scItemGroupSDO.getCode());
        });
    }

    private List<OrganizationSDO> convertToTree(List<OrganizationSDO> list, String rootId) {
        Map<String, OrganizationSDO> organizationSDOMap = Nullable.stream(list).collect(Collectors.toMap(OrganizationSDO::getId, item -> item, (a, b) -> a));
        List<OrganizationSDO> tree = new ArrayList<>();
        for (Map.Entry<String, OrganizationSDO> entry : organizationSDOMap.entrySet()) {
            OrganizationSDO organizationSDO = entry.getValue();
            organizationSDO.setLabel(organizationSDO.getName());
            organizationSDO.setValue(organizationSDO.getId());
            organizationSDO.setDisabled(organizationSDO.getStatus() == -1 ? true : false);
            String parentId = organizationSDO.getParentId();
            OrganizationSDO organizationSDOParent = organizationSDOMap.get(parentId);
            if (organizationSDOParent != null) {
                if (CollectionUtils.isEmpty(organizationSDOParent.getChildren())) {
                    organizationSDOParent.setChildren(new ArrayList<>());
                }
                organizationSDOParent.getChildren().add(organizationSDO);
            }
            if (Objects.equals(organizationSDO.getId(), rootId)) {
                tree.add(organizationSDO);
            }
        }
        return tree;
    }

    private List<OrganizationSDO> convertToTree2(List<OrganizationSDO> list, String rootId) {
        Map<String, OrganizationSDO> organizationSDOMap = Nullable.stream(list).collect(Collectors.toMap(OrganizationSDO::getId, item -> item, (a, b) -> a));
        List<OrganizationSDO> tree = new ArrayList<>();
        for (Map.Entry<String, OrganizationSDO> entry : organizationSDOMap.entrySet()) {
            OrganizationSDO organizationSDO = entry.getValue();
            organizationSDO.setLabel(organizationSDO.getName());
            organizationSDO.setValue(organizationSDO.getId());
            //organizationSDO.setDisabled(organizationSDO.getStatus() == -1?true:false);
            String parentId = organizationSDO.getParentId();
            OrganizationSDO organizationSDOParent = organizationSDOMap.get(parentId);
            if (organizationSDOParent != null) {
                if (CollectionUtils.isEmpty(organizationSDOParent.getChildren())) {
                    organizationSDOParent.setChildren(new ArrayList<>());
                }
                organizationSDOParent.getChildren().add(organizationSDO);
            }
            if (Objects.equals(organizationSDO.getId(), rootId)) {
                tree.add(organizationSDO);
            }
        }
        return tree;
    }

    private List<OrganizationSDO> convertToTrees(List<OrganizationSDO> list, List<String> rootIds) {
        Map<String, OrganizationSDO> organizationSDOMap = Nullable.stream(list).collect(Collectors.toMap(OrganizationSDO::getId, item -> item, (a, b) -> a));
        List<OrganizationSDO> tree = new ArrayList<>();
        for (Map.Entry<String, OrganizationSDO> entry : organizationSDOMap.entrySet()) {
            OrganizationSDO organizationSDO = entry.getValue();
            organizationSDO.setLabel(organizationSDO.getName());
            organizationSDO.setValue(organizationSDO.getId());
            organizationSDO.setDisabled(organizationSDO.getStatus() == -1 ? true : false);
            String parentId = organizationSDO.getParentId();
            OrganizationSDO organizationSDOParent = organizationSDOMap.get(parentId);
            if (organizationSDOParent != null) {
                if (CollectionUtils.isEmpty(organizationSDOParent.getChildren())) {
                    organizationSDOParent.setChildren(new ArrayList<>());
                }
                organizationSDOParent.getChildren().add(organizationSDO);
            }
            if (rootIds.stream().anyMatch(companyId -> companyId.equals(organizationSDO.getId()))) {
                tree.add(organizationSDO);
            }
        }
        return tree;
    }

    public void recursiveList(List<OrganizationSDO> list) {
        for (OrganizationSDO sdo : list) {
            if (Objects.equals(sdo.getType(), OrganizationTypeEnum.SALES_CHANNEL.getCode())) {
                sdo.setChildren(sortList(sdo.getChildren()));
                continue;
            }
            if (CollectionUtils.isNotEmpty(sdo.getChildren())) {
                recursiveChildren(sdo.getChildren());
            }
        }
    }

    public void recursiveChildren(List<OrganizationSDO> list) {
        for (OrganizationSDO sdo : list) {
            if (Objects.equals(sdo.getType(), OrganizationTypeEnum.SALES_CHANNEL.getCode())) {
                sdo.setChildren(sortList(sdo.getChildren()));
                continue;
            }
            if (CollectionUtils.isNotEmpty(sdo.getChildren())) {
                recursiveChildren(sdo.getChildren());
            }
        }
    }

    public List<OrganizationSDO> sortList(List<OrganizationSDO> list) {
        if (list == null) {
            return null;
        }
        List<OrganizationSDO> emptyCodeOrgs = new ArrayList<>();
        List<String> codeList = list.stream().map(x -> {
            if (StringUtil.isBlank(x.getCode())) {
                emptyCodeOrgs.add(x);
            }
            return x.getCode();
        }).collect(Collectors.toList());
        codeList = codeList.stream().filter(x -> StringUtil.isNotEmpty(x)).collect(Collectors.toList());

        String[] codes = new String[codeList.size()];
        codeList.toArray(codes);
        Arrays.sort(codes);

        Map<String, OrganizationSDO> orgMap = list.stream().collect(Collectors.toMap(OrganizationSDO::getCode, Function.identity(), (v1, v2) -> v1));
        List<OrganizationSDO> result = new ArrayList<>();
        for (String code : codes) {
            result.add(orgMap.get(code));
        }
        result.addAll(emptyCodeOrgs);
        return result;
    }
}